package se.lnu.axez.textures;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import android.content.res.Resources;

public final class TextureManager {
	private final TextureFactory factory;
	private final Map<Class<? extends ITexture>, ITexture> textures = new HashMap<Class<? extends ITexture>, ITexture>();

	public TextureManager(TextureFactory factory) {
		if (factory == null) {
			throw new IllegalArgumentException("shaderFactory cannot be null");
		}
		
		this.factory = factory;
	}
	
	public <E extends ITexture> E getTexture(Class<E> type) {
		if (this.textures.containsKey(type)) {
			return (E) this.textures.get(type);
		}

		try {
			E instance = this.factory.createNewInstance(type);
			this.textures.put(type, instance);
			return instance;
		} catch (Exception e) {
			// reconsider this
			throw new RuntimeException();
		}
	}
	
	public TextureManager loadTextures() {
		for (ITexture vs : this.textures.values()) {
			vs.load();
		}
		
		return this;
	}
	
	public TextureManager disposeAll() {
		// TODO: add logic
		return this;
	}
	
	public static final class TextureFactory {
		private Resources resources;
		
		public TextureFactory(Resources resources) {
			if (resources == null) {
				throw new IllegalArgumentException("resources cannot be null");
			}
			
			this.resources = resources;
		}
		
		private <E> E createNewInstance(Class<E> type)
				throws IllegalArgumentException, InstantiationException,
				IllegalAccessException, InvocationTargetException,
				SecurityException, NoSuchMethodException {
			Constructor<E> ctor = type.getConstructor(Resources.class);
			if (ctor != null) {
				return ctor.newInstance(this.resources);
			} else {
				return type.newInstance();
			}
		}
	}
}
